package com.roundarchisobar.njariwala;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.SimpleTimeZone;
import java.util.TreeMap;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestTemplate;

/**
 * Handles requests for the application home page.
 */
@Controller
public class OldHomeController {

	private static final Logger logger = LoggerFactory.getLogger(OldHomeController.class);
	private static final String API_KEY = "n5aaghacqp2heuv8vhanpjk6";
	private static final String SHARED_SECRET = "J7KRneCfWG";
	private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
	
	private static final String CATALOG_PEOPLE_URL = "http://api-public.netflix.com/catalog/people";

	private static final String REQUEST_TOKEN_URL = "http://api-public.netflix.com/oauth/request_token";
	
	private static Base64 base64 = new Base64();


	@Autowired
	private RestTemplate restTemplate;

	/**
	 * Simply selects the home view to render by returning its name.
	 * @throws UnsupportedEncodingException 
	 */
	@RequestMapping(value = "/sample", method = RequestMethod.GET)
	public String home(Locale locale, Model model) throws UnsupportedEncodingException {
		logger.info("Welcome home! The client locale is {}.", locale);
		String nonce = generateRandomHexString(16);
		String timestamp = System.currentTimeMillis() / 1000L + "";
		String signature = createSignature(nonce, timestamp, SHARED_SECRET);
		makeCall(nonce, timestamp, signature);
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

		String formattedDate = dateFormat.format(date);

		model.addAttribute("serverTime", formattedDate);

		return "home";
	}

	private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
			'e', 'f' };

	private void makeCall(String nonce, String timestamp, String signature) throws UnsupportedEncodingException {
		String URL = generateURLForRestCall(nonce,timestamp,signature);
		String response = restTemplate.getForObject(URL, String.class);
		logger.info("Response:" + response);
	}

	

	private String generateURLForRestCall(String nonce, String timestamp, String signature) throws UnsupportedEncodingException {
		StringBuilder sb = new StringBuilder(REQUEST_TOKEN_URL);
		sb.append("?");
		//sb.append("max_results").append("=").append(10);
		sb.append("").append("oauth_consumer_key").append("=").append(API_KEY);
		sb.append("&").append("oauth_nonce").append("=").append(nonce);
		sb.append("&").append("oauth_signature_method").append("=").append("HMAC-SHA1");
		sb.append("&").append("oauth_timestamp").append("=").append(timestamp);
		sb.append("&").append("oauth_version").append("=").append("1.0");
		sb.append("&").append("oauth_signature").append("=").append(signature);
		//sb.append("&").append("term").append("=").append("frances");

		return sb.toString();
	}

	private String createSignature(String nonce, String timestamp, String sharedSecret) {
		String signature = null;
		try {
			StringBuilder sb = new StringBuilder();
			sb.append("GET&").append(URLEncoder.encode(REQUEST_TOKEN_URL, "UTF-8")).append("&");

			StringBuilder sb2 = new StringBuilder();
			//sb2.append("max_results").append("=").append(10);
			sb2.append("").append("oauth_consumer_key").append("=").append(API_KEY);
			sb2.append("&").append("oauth_nonce").append("=").append(nonce);
			sb2.append("&").append("oauth_signature_method").append("=").append("HMAC-SHA1");
			sb2.append("&").append("oauth_timestamp").append("=").append(timestamp);
			sb2.append("&").append("oauth_version").append("=").append("1.0");
			//sb2.append("&").append("term").append("=").append("frances");

			String data = sb.append(URLEncoder.encode(sb2.toString(), "UTF-8")).toString();
			logger.info("signature function input:"+data);
			
			
			// get an hmac_sha1 key from the raw key bytes
			SecretKeySpec signingKey = new SecretKeySpec((sharedSecret + "&").getBytes("UTF-8"), HMAC_SHA1_ALGORITHM);
			// get an hmac_sha1 Mac instance and initialize with the signing key
			Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
			mac.init(signingKey);
			// compute the hmac on input data bytes
			//byte[] rawHmac = mac.doFinal(data.getBytes());
			// Compute the hmac on input data bytes
			// Convert raw bytes to Hex
			//byte[] hexBytes = new Hex().encode(rawHmac);
			// base64-encode the hmac
			//signature = new String(Base64.encodeBase64(rawHmac),"UTF-8");
			
			signature = new String(base64.encode(mac.doFinal(data.toString().getBytes(
	                "UTF-8"))), "UTF-8").trim();
			//signature = URLEncoder.encode(signature, "UTF-8");
			logger.info(signature);

		} catch (Exception e) {
			logger.error("Get MD5 Hash Method failed", e);
		}
		return signature;
	}

	private static String generateRandomHexString(int len) {
		StringBuilder hexString = new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			int j = (int) (Math.random() * 16);
			hexString.append(HEX_CHARS[j]);
		}
		return hexString.toString();
	}

	public RestTemplate getRestTemplate() {
		return restTemplate;
	}

	public void setRestTemplate(RestTemplate restTemplate) {
		this.restTemplate = restTemplate;
	}

}
